#include "inc/zg291hum_para.h"
#include "ui_zg291hum_para.h"
#include <QThread>
ZG291hum_para::ZG291hum_para(QSerialPort *serialPort,QTimer *m_timer,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ZG291hum_para),
    serialPort(serialPort),
    m_timer(m_timer)
{
    ui->setupUi(this);
}

ZG291hum_para::~ZG291hum_para()
{
    delete ui;
}

void ZG291hum_para::on_pushButton_clicked() // 读取参数按钮
{
    // 停止定时器（如果有）
    if (m_timer && m_timer->isActive()) {
        m_timer->stop();
    }

    // 检查串口状态
    if (!serialPort || !serialPort->isOpen()) {
        qDebug() << "Serial port not ready!";
//        if (m_timer) m_timer->start(2000);
        return;
    }

    /**************** 第一条指令：读取0x1B-0x24寄存器 (10个寄存器) ****************/
    QByteArray request1;
    request1.append(static_cast<char>(0x00));     // 从机地址
    request1.append(static_cast<char>(0x03));     // 功能码
    request1.append(static_cast<char>(0x00));     // 起始地址高字节
    request1.append(static_cast<char>(0x1B));     // 起始地址低字节 (0x1B)
    request1.append(static_cast<char>(0x00));     // 寄存器数高字节
    request1.append(static_cast<char>(0x0A));     // 寄存器数低字节 (10个寄存器)

    // 计算并附加CRC
    quint16 crc1 = calculateCRC(request1);
    request1.append(static_cast<char>(crc1 & 0xFF));
    request1.append(static_cast<char>((crc1 >> 8) & 0xFF));

    // 发送第一条指令
    if (serialPort->write(request1) == -1) {
        qDebug() << "Write failed (1):" << serialPort->errorString();
//        if (m_timer) m_timer->start(2000);
        return;
    }

    // 读取第一条响应
    QByteArray response1;
    if (serialPort->waitForReadyRead(1000)) {
        response1 = serialPort->readAll();
        while (serialPort->waitForReadyRead(100)) {
            response1 += serialPort->readAll();
        }
    } else {
        qDebug() << "Read timeout (1)";
        if (m_timer) m_timer->start(2000);
        return;
    }

    /**************** 第二条指令：读取0x80-0x81寄存器 (2个寄存器) ****************/
    QByteArray request2;
    request2.append(static_cast<char>(0x00));     // 从机地址
    request2.append(static_cast<char>(0x03));     // 功能码
    request2.append(static_cast<char>(0x00));     // 起始地址高字节
    request2.append(static_cast<char>(0x80));     // 起始地址低字节 (0x80)
    request2.append(static_cast<char>(0x00));     // 寄存器数高字节
    request2.append(static_cast<char>(0x02));     // 寄存器数低字节 (2个寄存器)

    // 计算并附加CRC
    quint16 crc2 = calculateCRC(request2);
    request2.append(static_cast<char>(crc2 & 0xFF));
    request2.append(static_cast<char>((crc2 >> 8) & 0xFF));

    // 发送第二条指令
    if (serialPort->write(request2) == -1) {
        qDebug() << "Write failed (2):" << serialPort->errorString();
//        if (m_timer) m_timer->start(2000);
        return;
    }

    // 读取第二条响应
    QByteArray response2;
    if (serialPort->waitForReadyRead(1000)) {
        response2 = serialPort->readAll();
        while (serialPort->waitForReadyRead(100)) {
            response2 += serialPort->readAll();
        }
    } else {
        qDebug() << "Read timeout (2)";
//        if (m_timer) m_timer->start(2000);
        return;
    }

    /**************** 解析响应数据并更新UI ****************/

    // 解析第一条响应 (0x1B-0x24) - 10个寄存器
    if (response1.size() >= 23) {  // 10寄存器×2 + 5字节头尾
        // 寄存器0x1B: 湿度报警上限
        quint16 hum_up = (static_cast<quint8>(response1[3]) << 8) | static_cast<quint8>(response1[4]);
        ui->hum_up->setText(QString::number(hum_up/10.0, 'f', 1));

        // 寄存器0x1C: 湿度报警上限回差
        quint16 hum_up_deff = (static_cast<quint8>(response1[5]) << 8) | static_cast<quint8>(response1[6]);
        ui->hum_up_deff->setText(QString::number(hum_up_deff/10.0, 'f', 1));

        // 寄存器0x1D: 湿度报警上限继电器
        quint16 hum_up_relay = (static_cast<quint8>(response1[7]) << 8) | static_cast<quint8>(response1[8]);
        ui->hum_up_relay->setCurrentIndex(hum_up_relay);

        // 寄存器0x1E: 湿度报警下限
        quint16 hum_down = (static_cast<quint8>(response1[9]) << 8) | static_cast<quint8>(response1[10]);
        ui->hum_down->setText(QString::number(hum_down/10.0, 'f', 1));

        // 寄存器0x1F: 湿度报警下限回差
        quint16 hum_down_deff = (static_cast<quint8>(response1[11]) << 8) | static_cast<quint8>(response1[12]);
        ui->hum_down_deff->setText(QString::number(hum_down_deff/10.0, 'f', 1));

        // 寄存器0x20: 湿度报警下限继电器
        quint16 hum_down_relay = (static_cast<quint8>(response1[13]) << 8) | static_cast<quint8>(response1[14]);
        ui->hum_down_relay->setCurrentIndex(hum_down_relay);

        // 寄存器0x21: 湿度预警上限
        quint16 hum_up_warnning = (static_cast<quint8>(response1[15]) << 8) | static_cast<quint8>(response1[16]);
        ui->hum_up_warnning->setText(QString::number(hum_up_warnning/10.0, 'f', 1));

        // 寄存器0x22: 湿度预警上限开关
        quint16 hum_up_warning_en = (static_cast<quint8>(response1[17]) << 8) | static_cast<quint8>(response1[18]);
        ui->hum_up_warning_en->setCurrentIndex(hum_up_warning_en);

        // 寄存器0x23: 湿度预警下限
        quint16 hum_down_warning = (static_cast<quint8>(response1[19]) << 8) | static_cast<quint8>(response1[20]);
        ui->hum_down_warning->setText(QString::number(hum_down_warning/10.0, 'f', 1));

        // 寄存器0x24: 湿度预警下限开关
        quint16 hum_down_warning_en = (static_cast<quint8>(response1[21]) << 8) | static_cast<quint8>(response1[22]);
        ui->hum_down_warning_en->setCurrentIndex(hum_down_warning_en);
    } else {
        qDebug() << "Invalid response1 length:" << response1.size();
    }

    // 解析第二条响应 (0x80-0x81) - 2个寄存器
    if (response2.size() >= 7) {  // 2寄存器×2 + 5字节头尾
        // 寄存器0x80: 湿度校准系数
        quint16 hum_K = (static_cast<quint8>(response2[3]) << 8) | static_cast<quint8>(response2[4]);
        ui->hum_K->setText(QString::number(hum_K/10.0, 'f', 1));

        // 寄存器0x81: 湿度零点偏移
        quint16 hum_B = (static_cast<quint8>(response2[5]) << 8) | static_cast<quint8>(response2[6]);
        ui->hum_B->setText(QString::number(hum_B/10.0, 'f', 1));
    } else {
        qDebug() << "Invalid response2 length:" << response2.size();
    }

    // 恢复定时器（如果有）
//    if (m_timer) m_timer->start(2000);
}

void ZG291hum_para::on_pushButton_2_clicked()
{
    // 停止定时器（如果有）
    if (m_timer && m_timer->isActive()) {
        m_timer->stop();
    }

    // 检查串口状态
    if (!serialPort || !serialPort->isOpen()) {
        qDebug() << "Serial port not ready!";
        return;
    }

    // 从UI获取所有参数值并转换为设备格式（×10）
    quint16 hum_up = static_cast<quint16>(ui->hum_up->text().toFloat() * 10);
    quint16 hum_up_deff = static_cast<quint16>(ui->hum_up_deff->text().toFloat() * 10);
    quint16 hum_up_relay = static_cast<quint16>(ui->hum_up_relay->currentIndex());
    quint16 hum_down = static_cast<quint16>(ui->hum_down->text().toFloat() * 10);
    quint16 hum_down_deff = static_cast<quint16>(ui->hum_down_deff->text().toFloat() * 10);
    quint16 hum_down_relay = static_cast<quint16>(ui->hum_down_relay->currentIndex());
    quint16 hum_up_warnning = static_cast<quint16>(ui->hum_up_warnning->text().toFloat() * 10);
    quint16 hum_up_warning_en = static_cast<quint16>(ui->hum_up_warning_en->currentIndex());
    quint16 hum_down_warning = static_cast<quint16>(ui->hum_down_warning->text().toFloat() * 10);
    quint16 hum_down_warning_en = static_cast<quint16>(ui->hum_down_warning_en->currentIndex());
    quint16 hum_K = static_cast<quint16>(ui->hum_K->text().toFloat() * 10);
    quint16 hum_B = static_cast<quint16>(ui->hum_B->text().toFloat() * 10);

    // 第一组写入：0x1B-0x24 (10个连续寄存器)
    {
        QByteArray request;
        request.append(static_cast<char>(0x00));     // 从机地址
        request.append(static_cast<char>(0x10));    // 功能码10(写多个寄存器)
        request.append(static_cast<char>(0x00));    // 起始地址高字节
        request.append(static_cast<char>(0x1B));    // 起始地址低字节(0x1B)
        request.append(static_cast<char>(0x00));    // 寄存器数量高字节
        request.append(static_cast<char>(0x0A));    // 寄存器数量低字节(10个)
        request.append(static_cast<char>(0x14));    // 字节数(10寄存器×2=20字节=0x14)

        // 按顺序添加所有寄存器值
        request.append(static_cast<char>(hum_up >> 8));
        request.append(static_cast<char>(hum_up & 0xFF));
        request.append(static_cast<char>(hum_up_deff >> 8));
        request.append(static_cast<char>(hum_up_deff & 0xFF));
        request.append(static_cast<char>(hum_up_relay >> 8));
        request.append(static_cast<char>(hum_up_relay & 0xFF));
        request.append(static_cast<char>(hum_down >> 8));
        request.append(static_cast<char>(hum_down & 0xFF));
        request.append(static_cast<char>(hum_down_deff >> 8));
        request.append(static_cast<char>(hum_down_deff & 0xFF));
        request.append(static_cast<char>(hum_down_relay >> 8));
        request.append(static_cast<char>(hum_down_relay & 0xFF));
        request.append(static_cast<char>(hum_up_warnning >> 8));
        request.append(static_cast<char>(hum_up_warnning & 0xFF));
        request.append(static_cast<char>(hum_up_warning_en >> 8));
        request.append(static_cast<char>(hum_up_warning_en & 0xFF));
        request.append(static_cast<char>(hum_down_warning >> 8));
        request.append(static_cast<char>(hum_down_warning & 0xFF));
        request.append(static_cast<char>(hum_down_warning_en >> 8));
        request.append(static_cast<char>(hum_down_warning_en & 0xFF));

        // 计算CRC
        quint16 crc = calculateCRC(request);
        request.append(static_cast<char>(crc & 0xFF));
        request.append(static_cast<char>((crc >> 8) & 0xFF));

        // 发送请求
        if (serialPort->write(request) == -1) {
            qDebug() << "Write failed (0x1B-0x24):" << serialPort->errorString();
            return;
        }

        // 读取响应
        if (serialPort->waitForReadyRead(1000)) {
            QByteArray response = serialPort->readAll();
            while (serialPort->waitForReadyRead(100)) {
                response += serialPort->readAll();
            }

            // 验证响应(正常响应应为6字节：地址+功能码+起始地址+寄存器数量+CRC)
            if (response.size() < 6 ||
                static_cast<quint8>(response[0]) != 0x00 ||
                static_cast<quint8>(response[1]) != 0x10 ||
                static_cast<quint8>(response[2]) != 0x00 ||
                static_cast<quint8>(response[3]) != 0x1B ||
                static_cast<quint8>(response[4]) != 0x00 ||
                static_cast<quint8>(response[5]) != 0x0A) {
                qDebug() << "Verify failed (0x1B-0x24)";
                return;
            }
        } else {
            qDebug() << "Timeout (0x1B-0x24)";
            return;
        }
        QThread::msleep(50);
    }

    // 第二组写入：0x80-0x81 (2个连续寄存器)
    {
        QByteArray request;
        request.append(static_cast<char>(0x00));     // 从机地址
        request.append(static_cast<char>(0x10));    // 功能码10
        request.append(static_cast<char>(0x00));    // 起始地址高字节
        request.append(static_cast<char>(0x80));    // 起始地址低字节(0x80)
        request.append(static_cast<char>(0x00));    // 寄存器数量高字节
        request.append(static_cast<char>(0x02));    // 寄存器数量低字节(2个)
        request.append(static_cast<char>(0x04));   // 字节数(2寄存器×2=4字节)

        // 添加寄存器值
        request.append(static_cast<char>(hum_K >> 8));
        request.append(static_cast<char>(hum_K & 0xFF));
        request.append(static_cast<char>(hum_B >> 8));
        request.append(static_cast<char>(hum_B & 0xFF));

        // 计算CRC
        quint16 crc = calculateCRC(request);
        request.append(static_cast<char>(crc & 0xFF));
        request.append(static_cast<char>((crc >> 8) & 0xFF));

        // 发送请求
        if (serialPort->write(request) == -1) {
            qDebug() << "Write failed (0x80-0x81):" << serialPort->errorString();
            return;
        }

        // 读取响应
        if (serialPort->waitForReadyRead(1000)) {
            QByteArray response = serialPort->readAll();
            while (serialPort->waitForReadyRead(100)) {
                response += serialPort->readAll();
            }

            // 验证响应
            if (response.size() < 6 ||
                static_cast<quint8>(response[0]) != 0x00 ||
                static_cast<quint8>(response[1]) != 0x10 ||
                static_cast<quint8>(response[2]) != 0x00 ||
                static_cast<quint8>(response[3]) != 0x80 ||
                static_cast<quint8>(response[4]) != 0x00 ||
                static_cast<quint8>(response[5]) != 0x02) {
                qDebug() << "Verify failed (0x80-0x81)";
                return;
            }
        } else {
            qDebug() << "Timeout (0x80-0x81)";
            return;
        }
    }

    qDebug() << "All humidity parameters written successfully";
    // 恢复定时器（如果有）
    // if (m_timer) m_timer->start(2000);
}
